home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et3_0-a1.lha / et3 / src / PROGENV / SrcBrowser.C < prev    next >
C/C++ Source or Header  |  1992-07-09  |  14KB  |  597 lines

  1. #ifdef __GNUG__
  2. #pragma implementation
  3. #endif
  4.  
  5. #include "CodeTextView.h"       // cpp: max nesting level
  6. #include "SrcBrowser.h"
  7.  
  8. #include "ET++.h"
  9.  
  10. #include "StyledText.h"
  11. #include "TextFormatter.h"
  12. #include "OrdColl.h"
  13. #include "WindowSystem.h"
  14. #include "PathLookup.h"
  15. #include "GotoDialog.h"
  16. #include "ClassManager.h"
  17. #include "MenuBar.h"
  18. #include "Env.h"
  19. #include "Data.h"
  20. #include "FindChange_e.h"
  21. #include "Math.h"
  22. #include "Fields.h"
  23.  
  24. #include "EtProgEnv.h"
  25. #include "ClassList.h"
  26. #include "MethodB.h"
  27. #include "EtPeCmdNo.h"
  28. #include "EtPeManager.h"
  29. #include "EtPeTool.h"
  30.  
  31. //---- SourceBrowser -----------------------------------------------------------
  32.  
  33. NewMetaImpl(PeSourceBrowser, Document, (TP(textview), TP(listview), TP(text), TP(ccl), TP(log),
  34.                                 TB(isCCode)));
  35. int PeSourceBrowser::srcCount;
  36. PeSourceBrowser *PeSourceBrowser::browser;
  37.  
  38. PeSourceBrowser::PeSourceBrowser(Manager *m) : Document(cDocTypeAscii)
  39. {
  40.     m->AddManager(this);
  41.     Font *fd= gFixedFont;
  42.     if (Env::GetValue("CodeText.UseStyles", TRUE))
  43.     text= new StyledText(256, fd);
  44.     else
  45.     text= new GapText(256, fd);
  46.     text->SetDefTab(fd->Width(' ') * Env::GetValue("CodeText.TabPos", 8));
  47.  
  48.     ccl= 0;
  49.     definition= FALSE;
  50.     log= new OrdCollection;
  51.     isCCode= FALSE;
  52.     base= (srcCount++ == 0);
  53. }
  54.  
  55. PeSourceBrowser::~PeSourceBrowser()
  56. {
  57.     SafeDelete(textview);
  58.     SafeDelete(listview);
  59.     SafeDelete(text);
  60.     SafeDelete(log);
  61.     SafeDelete(methods);
  62.     SafeDelete(implementors);
  63. }
  64.  
  65. VObject *PeSourceBrowser::DoMakeContent()
  66. {   
  67.     textview= new PeSrcBrowserTextView(this, Rectangle(Point(2000,cFit)), text);
  68.     listview= new PeClassListView(this);
  69.     methods= new PeMethodBrowser(this);
  70.     implementors= new PeImplementors(this);
  71.     SetFirstHandler(textview);
  72.     classScroller= new Scroller(listview, Point(-1, 100));
  73.     classScroller->SetFlag(eVObjHFixed);
  74.  
  75.     methodScroller= new Scroller(methods);
  76.  
  77.     implTitle= new TextField(cIdNone, 20, gFixedFont->WithFace(eFaceItalic));
  78.     implTitle->SetEditable(FALSE);
  79.     
  80.     return
  81.     new VExpander(gPoint2, 
  82.         new HBox(gPoint2, (VObjAlign)(eVObjHExpand|eVObjVEqual),
  83.         classScroller,
  84.         methodScroller,
  85.         //new VExpander(gPoint2,
  86.         new VBox(gPoint2, (VObjAlign)(eVObjVExpand|eVObjHExpand),
  87.             implTitle,
  88.             new Scroller(implementors),
  89.             0
  90.         ),
  91.         0
  92.         ),
  93.         new Scroller(textview, Point(550, 300)),
  94.         0
  95.     );
  96. }
  97.  
  98. void PeSourceBrowser::InputKbd(Token &t)
  99. {
  100.     if (EtPeTool::WantGrabKeyToken(t, classScroller))
  101.     classScroller->Input(t.Pos, t, GetWindow());
  102.     else if (EtPeTool::WantGrabKeyToken(t, methodScroller))
  103.     methodScroller->Input(t.Pos, t, GetWindow());
  104.     else
  105.     Document::InputKbd(t);
  106. }
  107.  
  108. bool PeSourceBrowser::LoadData(Data *d, bool unique)
  109. {
  110.     bool ok= Document::LoadData(d, unique);
  111.     if (ok) {
  112.     ccl= 0;
  113.     listview->SelectClass(ccl);
  114.     methods->ShowMethodsOf(ccl);
  115.     }
  116.     return ok;
  117. }
  118.  
  119. void PeSourceBrowser::SetWindowTitle(char *name)
  120. {
  121.     if (base)
  122.     GetWindow()->SetTitle(form("*** %s ***", name));
  123.     else
  124.     Document::SetWindowTitle(name);
  125. }
  126.  
  127. bool PeSourceBrowser::CanImport(Data *data)
  128. {
  129.     if (data)
  130.     return data->CanConvert(Meta(Text));
  131.     return TRUE;
  132. }
  133.  
  134. Command *PeSourceBrowser::DoImport(Data *data)
  135. {
  136.     Text *t;
  137.     if (t= (Text*) data->AsObject(Meta(Text))) {
  138.     Command *cmd= textview->InsertText(t);
  139.     SafeDelete(t);
  140.     return cmd;
  141.     }
  142.     return gNoChanges;
  143. }
  144.  
  145. bool PeSourceBrowser::DoWrite(OStream &s, Data*)
  146. {
  147.     // ??? terminate last line with a '\n' ???
  148.     if ((*text)[text->Size()-1] != '\n')
  149.     text->Append('\n');
  150.     text->PrintOnAsPureText(s);
  151.     return TRUE;
  152. }
  153.  
  154. bool PeSourceBrowser::DoReadData(Data *data)
  155. {
  156.     IStream s(data->GetStreamBuf());
  157.     text->ReadFromAsPureText(s, data->SizeHint());
  158.     if (isCCode= data->IsCCode())
  159.     textview->FormatCode();
  160.     else
  161.     textview->SetDefaultStyle();
  162.     textview->SetText(text);
  163.     return TRUE;
  164. }
  165.  
  166. void PeSourceBrowser::RevealAndSelectLine(int l)
  167. {
  168.     LineMark *lm= textview->MarkAtLine(Math::Range(0, textview->Lines()-1, l-1));
  169.     textview->SetSelection(lm->Pos(),lm->End());
  170.     Rectangle r= textview->SelectionRect();
  171.     textview->Scroll(cPartScrollAbs, Point(0,r.origin.y)+Point(0,2));
  172. }
  173.  
  174. void PeSourceBrowser::Log(Class *cl)
  175. {
  176.     if (cl != ccl)
  177.     log->Add(cl);
  178. }
  179.  
  180. void PeSourceBrowser::Control(int id, int what, void *val)
  181. {
  182.     PeMethodReference *mr= (PeMethodReference *)val;
  183.     
  184.     switch (what) {
  185.     case cPeCLChangedClass:
  186.     SetClass((Class*)val, definition);
  187.     break;
  188.     
  189.     case cPeChangedMethod:
  190.     RevealMethod(mr);
  191.     break;
  192.     
  193.     case cPeImplementors:
  194.     { 
  195.         GrShowWaitCursor wc;
  196.         implTitle->SetFString(TRUE, "implementors of: %s", mr->Str());
  197.         implementors->ShowImplementorsOf(mr, FALSE);
  198.     }
  199.     break;
  200.     
  201.     case cPeInherited:
  202.     implTitle->SetFString(TRUE, "inherited: %s", mr->Str());
  203.     implementors->ShowInherited(mr);
  204.     break;
  205.     
  206.     case cPeOverrides:
  207.     implTitle->SetFString(TRUE, "overrides of: %s", mr->Str());
  208.     implementors->ShowImplementorsOf(mr, TRUE);
  209.     break;
  210.     
  211.     default:
  212.     Document::Control(id, what, val);
  213.     }
  214. }
  215.  
  216. void PeSourceBrowser::SetClass(Class *cl, bool what, bool reveal)
  217. {
  218.     Log(cl);
  219.     DoSetClass(cl, what, TRUE, reveal);
  220. }
  221.  
  222. void PeSourceBrowser::RevealMethod(PeMethodReference *mr)
  223. {
  224.     SetClass(mr->GetClass(), FALSE, FALSE);
  225.     textview->ShowMethod(mr);
  226.     methods->SelectMethod(mr);
  227. }
  228.  
  229. void PeSourceBrowser::DoSetClass(Class *cl, bool decl, bool unique, bool reveal)
  230. {
  231.     char fname[1000];
  232.     bool sameClass= (cl == ccl && decl == definition);
  233.     bool sameFile= FALSE;
  234.  
  235.     if (!sameClass) {
  236.     if (!gEtPeManager->FileOfClass(cl, fname, decl)) {
  237.         ShowAlert(eAlertNote, "Can't find file @B%s@P in Env::SrcPath\n",
  238.                                 BaseName(fname));
  239.         return;
  240.     }
  241.  
  242.     FileData *fd= new FileData(fname);
  243.     if (fd->UniqueId() != UniqueId()) {
  244.         if (! LoadData(fd, unique)) {
  245.         listview->SelectClass(ccl);
  246.         return;
  247.         }
  248.     } else {
  249.         sameFile= TRUE;
  250.         delete fd;
  251.     }
  252.     definition= decl;
  253.     ccl= cl;
  254.     listview->SelectClass(ccl);
  255.     Send(cPeSourceBrowser, cPeCLSelectClass, ccl);
  256.     methods->ShowMethodsOf(cl);
  257.     SafeDelete(fd);     
  258.     }
  259.     if (reveal)
  260.     SelectSourceLine(sameFile);   
  261. }
  262.  
  263. void PeSourceBrowser::SelectSourceLine(bool)
  264. {
  265.     int line;
  266.     if (definition)
  267.     line= ccl->GetDeclFileLine();
  268.     else 
  269.     line= ccl->GetImplFileLine();
  270.  
  271.     RevealAndSelectLine(line);
  272. }
  273.  
  274. void PeSourceBrowser::SetMode(bool what)
  275. {
  276.     SetClass(ccl, what);
  277. }
  278.     
  279. void PeSourceBrowser::Spawn()
  280. {
  281.     SavedChanges();
  282.     Spawn(gEtPeManager, ccl, definition);
  283. }
  284.  
  285. void PeSourceBrowser::EditSelectedClass()
  286. {
  287.     char *classname= FirstWordOfSelection();
  288.     Class *clp= gClassManager->Find(classname);
  289.     if (clp)
  290.     SetClass(clp,definition);
  291.     else
  292.     ShowAlert(eAlertNote, "No Metaclass found for \"%s\" ?", classname);
  293. }
  294.  
  295. void PeSourceBrowser::ShowImplementors()
  296. {
  297.     PeMethodReference mr(0, 0, FirstWordOfSelection(), FALSE);
  298.     implementors->ShowImplementorsOf(&mr, FALSE);
  299. }
  300.  
  301. void PeSourceBrowser::InspectSomeInstance()
  302.     Object *op= ccl->SomeMember();
  303.     if (!op)
  304.     op= ccl->SomeInstance();
  305.     if (op)
  306.     op->Inspect();
  307.     else
  308.     ShowAlert(eAlertNote, "No instances found");
  309. }
  310.  
  311. MenuBar *PeSourceBrowser::DoMakeMenuBar()
  312. {
  313.     MenuBar *mb= Document::DoMakeMenuBar();
  314.     
  315.     //---- file menu
  316.     Menu *m= new Menu("Classes");
  317.     m->AppendItems( "Other",                  cEDITOTHER,
  318.             "Superclass",             cEDITSUPER,
  319.             "Spawn",                  cSPAWN,
  320.             "-",
  321.             "Inspect Some Instance",  cINSPECTSOME,
  322.             "-",
  323.             "Show in Hierarchy",      cSHOWHIERARCHY,
  324.             "-",
  325.             "Previous Class",         cGOBACK,
  326.             "Empty Classes",          cEMPTYCLASSES,
  327.             0);
  328.     mb->AddMenu(m);
  329.  
  330.     m= new Menu("Methods");
  331.     m->AppendItems( "Implementors",     cIMPLEMENTORS,
  332.             "Overrides",        cOVERRIDES,
  333.             "Inherited",        cINHERITED,
  334.             "References",       cMETHREFERENCES,
  335.             "-",
  336.             "Filter...",        cFILTER,
  337.             "Remove Filter",    cREMFILTER,
  338.             0);
  339.     mb->AddMenu(m);
  340.     
  341.     m= new Menu("Utilities");
  342.     m->AppendItems( "Edit Selected Class",    cEDITSELECTED,
  343.             "Go to Line...",          cGOTOLINE,
  344.             "Reformat",               cREFORMATCODE,
  345.             0);
  346.     mb->AddMenu(m);
  347.  
  348.     FindChange::InstallChange(mb, textview);
  349.     
  350.     return mb;
  351. }
  352.  
  353. void PeSourceBrowser::DoSetupMenu(Menu *menu)
  354. {
  355.     menu->ToggleItem(cEDITOTHER, definition, "Implementation", "Definition");
  356.  
  357.     if (ccl)
  358.     menu->EnableItems(cEDITOTHER, 
  359.               cSPAWN, 
  360.               cSHOWHIERARCHY,
  361.               cSHOWINHPATH, 
  362.               cINSPECTSOME,
  363.               cUTILMENU,
  364.               0);
  365.               
  366.     if (isCCode && text->IsKindOf(StyledText))
  367.     menu->EnableItem(cREFORMATCODE);
  368.  
  369.     menu->EnableItems(cGOTOLINE, cEMPTYCLASSES, 0);
  370.     
  371.     if (ccl && ccl->Super())
  372.     menu->EnableItem(cEDITSUPER);
  373.     if (log->Size() > 1)
  374.     menu->EnableItem(cGOBACK);
  375.      
  376.     menu->ToggleItem(cEMPTYCLASSES, listview->HideEmptyClasses(), 
  377.              "Show All Classes",
  378.              "Hide Classes with no Instances");
  379.     
  380.     menu->ReplaceItem(cEDITSELECTED, "Selected Class/Method");
  381.     if (!textview->Caret()) {
  382.     char *q= FirstWordOfSelection();
  383.     if (strlen(q)) {
  384.         menu->ReplaceItem(cEDITSELECTED, form("Show \"%s\"", q));
  385.         menu->EnableItem(cEDITSELECTED);
  386.     }
  387.     }
  388.     
  389.     if (methods->GetSelectedMethod() != 0) {
  390.     menu->EnableItem(cIMPLEMENTORS);
  391.     menu->EnableItem(cOVERRIDES);
  392.     menu->EnableItem(cINHERITED);
  393.     }
  394.     menu->EnableItems(cFILTER, cREMFILTER, 0);
  395.     
  396.     Document::DoSetupMenu(menu);
  397. }
  398.  
  399. char *PeSourceBrowser::FirstWordOfSelection()
  400. {
  401.     static byte buf[60];
  402.     textview->SelectionAsString(buf, sizeof buf);
  403.     for (byte *q= buf; *q; q++)
  404.     if (Isinword(*q)) break;
  405.     for (byte *p= q; *p; p++)
  406.     if (!Isinword(*p)) break;
  407.     *p= '\0';
  408.     return (char*) q;
  409. }
  410.  
  411. Command *PeSourceBrowser::DoMenuCommand(int cmd)
  412. {
  413.     char *q;
  414.     PeMethodItem *mi= methods->GetSelectedMethod();
  415.     
  416.     switch (cmd) {
  417.  
  418.     case cFIND:
  419.     FindChange::ShowChangeDialog(textview);
  420.     break;
  421.     
  422.     case cEDITOTHER:
  423.     SetMode(!definition);
  424.     break;
  425.     
  426.     case cEDITSUPER:
  427.     SetClass(ccl->Super(), definition);
  428.     break;
  429.     
  430.     case cINSPECTSOME:
  431.     InspectSomeInstance();
  432.     break;
  433.     
  434.     case cEDITSELECTED:
  435.     { 
  436.     GrShowWaitCursor wc;
  437.     q= FirstWordOfSelection();
  438.     if (gClassManager->Find(q))
  439.         EditSelectedClass();
  440.     else
  441.         ShowImplementors();
  442.     }
  443.     break;
  444.     
  445.     case cEMPTYCLASSES:
  446.     listview->ToggleHideEmpty();
  447.     listview->SelectClass(ccl);
  448.     break;
  449.     
  450.     case cGOBACK:
  451.     log->RemoveAt(log->Size()-1);
  452.     DoSetClass((Class*)log->Last(), definition, TRUE, TRUE);
  453.     break;
  454.  
  455.     case cSPAWN:
  456.     Spawn();
  457.     break;
  458.     
  459.     case cSHOWHIERARCHY:
  460.     gEtPeManager->Control(cPeSourceBrowser, cPeShowHierarchy, ccl);
  461.     break;
  462.     
  463.     case cGOTOLINE:
  464.     GotoLine(textview);
  465.     break;
  466.     
  467.     case cREFORMATCODE:
  468.     textview->FormatCode();
  469.     textview->RepairAll();
  470.     return gNoChanges;
  471.  
  472.     case cIMPLEMENTORS:
  473.     Control(cPeSourceBrowser, cPeImplementors, mi->mrp);
  474.     break;
  475.     
  476.     case cOVERRIDES:
  477.     Control(cPeSourceBrowser, cPeOverrides, mi->mrp);
  478.     break;
  479.     
  480.     case cINHERITED:
  481.     Control(cPeSourceBrowser, cPeInherited, mi->mrp);
  482.     break;
  483.     
  484.     case cFILTER:
  485.     methods->Filter();
  486.     break;    
  487.  
  488.     case cREMFILTER:
  489.     methods->RemoveFilter();
  490.     break;    
  491.  
  492.     default:
  493.     break;
  494.     }
  495.     return Document::DoMenuCommand(cmd);
  496. }
  497.  
  498. void PeSourceBrowser::CollectParts(Collection *col)
  499. {
  500.     EvtHandler::CollectParts(col);
  501. }
  502.  
  503. void PeSourceBrowser::Spawn(Manager *m, Class *cp, bool decl, int at)
  504. {
  505.     PeSourceBrowser *sb= new PeSourceBrowser(m);
  506.     sb->SetOnDismiss(eMgrClose);
  507.     sb->Show();
  508.     sb->DoSetClass(cp, decl, FALSE, at == -1);
  509.     if (at != -1) 
  510.     sb->RevealAndSelectLine(at);
  511. }
  512.  
  513. void PeSourceBrowser::ShowClass(Manager *m, Class *cp, bool decl, int at)
  514. {
  515.     if (browser == 0)
  516.     browser= new PeSourceBrowser(m);
  517.     browser->Show();
  518.     browser->SetClass(cp, decl, at == -1);
  519.     if (at != -1) 
  520.     browser->RevealAndSelectLine(at);
  521. }
  522.  
  523. //---- PeSrcBrowserTextView ------------------------------------------------------
  524.  
  525. NewMetaImpl0(PeSrcBrowserTextView, CodeTextView);
  526.  
  527. PeSrcBrowserTextView::PeSrcBrowserTextView(EvtHandler *eh, Rectangle r, Text *t)
  528.                            : CodeTextView(eh, r, t)
  529. {
  530. }
  531.  
  532. PrettyPrinter *PeSrcBrowserTextView::MakePrettyPrinter(Text *t, 
  533.             CharStyle *cs, CharStyle *fs, CharStyle *cds, CharStyle *ps)
  534. {
  535.     return new PeSrcBrowserPPrinter(this, t, cs, fs, cds, ps);
  536. }
  537.  
  538. void PeSrcBrowserTextView::ShowMethod(PeMethodReference *mr)
  539. {
  540.     MarkList *mlp= GetMarkList();
  541.     Iter next(mlp->MakeIterator());
  542.     PeMethodMark *mp;
  543.     bool found= FALSE;
  544.     
  545.     while (mp= (PeMethodMark*)next()) {
  546.     if (strcmp(mp->className, mr->GetClass()->Name()) == 0 &&
  547.                  strcmp(mp->method, (char*)mr->Str()) == 0) {
  548.         SetSelection(mp->Pos(),mp->End());
  549.         found= TRUE;
  550.         break;
  551.     }
  552.     }
  553.     // no mark found, use position information stored in mr
  554.     if (!found) {
  555.     LineMark *lm= MarkAtLine(Math::Range(0, Lines()-1, mr->Line()-1));
  556.     SetSelection(lm->Pos(),lm->End());
  557.     }
  558.     Rectangle r= SelectionRect();
  559.     Scroll(cPartScrollAbs, Point(0,r.origin.y)+Point(0,-4));
  560. }
  561.  
  562. //---- PeSrcBrowserPPrinter ------------------------------------------------------
  563.  
  564. PeSrcBrowserPPrinter::PeSrcBrowserPPrinter(PeSrcBrowserTextView *tv, Text *t, 
  565.             CharStyle *cs, CharStyle *fs, CharStyle *cds, CharStyle *ps)
  566.                          : PrettyPrinter(t, cs, fs, cds, ps)
  567. {
  568.     tvp= tv;
  569.     tv->GetMarkList()->FreeAll();
  570. }
  571.  
  572. void PeSrcBrowserPPrinter::Function(int line, int start, int end, char *name, char *classname)
  573. {
  574.     PrettyPrinter::Function(line, start, end, name, classname);
  575.  
  576.     if (classname) 
  577.     tvp->AddMark(new PeMethodMark(classname, name, start, end-start));
  578. }
  579.  
  580. //---- PeMethodMark --------------------------------------------------------------
  581.  
  582. NewMetaImpl(PeMethodMark, Mark, (TP(className), TP(method)));
  583.     
  584. PeMethodMark::PeMethodMark(char *c, char *m, int p, int l) : Mark(p, l)
  585. {
  586.     className= strsave(c);
  587.     method= strsave(m);
  588. }
  589.  
  590. PeMethodMark::~PeMethodMark()
  591. {
  592.     SafeDelete(className);
  593.     SafeDelete(method);
  594. }
  595.  
  596.